import random
import re
from datetime import datetime

from flask import request, current_app, jsonify, make_response, session

from info import redis_store, constants, db
from info.models import User
from info.utils.response_code import RET
from . import passport_blue
from info.utils.captcha.captcha import captcha
from info.libs.yuntongxun.sms import CCP

"""
退出接口
URL:/logout
请求方式：POST
"""


@passport_blue.route('/logout', methods=['POST'])
def logout():
	# 清除session信息
	session.pop('user_id', None)
	session.pop('mobile', None)
	session.pop('nick_name', None)
	session.pop('is_admin', None)

	return jsonify(errno=RET.OK, errmsg='退出成功')


"""
登录接口
URL：/login
请求方式：POST
参数：mobile（手机号）、password（密码）
"""


@passport_blue.route('/login', methods=['POST'])
def login():
	# 1.获取参数
	params_dict = request.json
	mobile = params_dict['mobile']
	password = params_dict['password']

	# 2.校验参数
	# 2.1参数完整性
	if not all([mobile, password]):
		return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

	# 2.2手机号码格式
	if not re.match(r'^1[3456789]\d{9}$', mobile):
		return jsonify(errno=RET.DATAERR, errmsg='手机号码格式错误')

	# 3.逻辑处理
	# 3.1判断是否注册过，通过手机号，数据库中查询
	try:
		user = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='数据库查询失败')

	# 3.2 判断user是否存在
	if not user:
		return jsonify(errno=RET.NODATA, errmsg='用户名不存在')

	# 3.3对比密码
	if not user.check_passowrd(password):
		return jsonify(errno=RET.PWDERR, errmsg='用户名或密码错误')

	# 4.保存登录状态
	session['user_id'] = user.id
	session['nick_name'] = mobile
	session['mobile'] = mobile

	# 设置最后登录时间
	user.last_login = datetime.now()

	# 返回正确信息
	return jsonify(errno=RET.OK, errmsg='登录成功')


"""
注册接口
URL：/register
请求方式：POST
参数：mobile（手机号）、sms_code（短信验证码）、password（密码）
"""


@passport_blue.route('/register', methods=['POST'])
def register():
	# 1.获取参数
	params_dict = request.json
	mobile = params_dict['mobile']
	sms_code = params_dict['sms_code']
	password = params_dict['password']

	# 2.校验参数
	# 2.1参数完整性
	if not all([mobile, sms_code, passport_blue]):
		return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

	# 2.2手机号码格式
	if not re.match(r'^1[3456789]\d{9}$', mobile):
		return jsonify(errno=RET.DATAERR, errmsg='手机号码格式错误')

	# 3.逻辑处理
	# 3.1 redis中取出短信验证码
	try:
		real_sms_code = redis_store.get('SMS_' + mobile)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='查询短信验证码失败')

	# 3.2 判断短信验证码是否过期
	if not real_sms_code:
		return jsonify(errno=RET.NODATA, errmsg='短信验证码已过期')

	# 3.3 对比短信验证码
	if real_sms_code.upper() != sms_code.upper():
		return jsonify(errno=RET.DATAERR, errmsg='短信验证码输入错误')

	# 4 判断是否注册过
	# 4.1 redis中查找mobile
	try:
		user = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='查询mobile失败')

	# 4.2 判断是否存在user
	if user:
		return jsonify(errno=RET.DATAEXIST, errmsg='该用户已注册')

	# 5.保存用户信息
	user = User()
	user.mobile = mobile
	user.nick_name = mobile
	user.password = password

	try:
		db.session.add(user)
		db.session.commit()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='数据库添加失败')

	# 6.保持登录状态
	session['user_id'] = user.id
	session['nick_name'] = user.nick_name
	session['mobile'] = user.mobile

	# 返回成功信息
	return jsonify(errno=RET.OK, errmsg='注册成功')


"""
注册短信验证码接口
URL：/sms_code
请求方式：POST
参数：mobile（手机号）、image_code（验证码图像内容）、image_code_id(图像验证码编号)
"""


@passport_blue.route('/sms_code', methods=['POST'])
def get_sms_code():
	# 1.获取参数
	params_dict = request.json
	mobile = params_dict['mobile']
	image_code = params_dict['image_code']
	image_code_id = params_dict['image_code_id']

	# 2.校验参数
	# 2.1参数完整性
	if not all([mobile, image_code, image_code_id]):
		return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

	# 2.2手机号码格式
	if not re.match(r'^1[3456789]\d{9}$', mobile):
		return jsonify(errno=RET.DATAERR, errmsg='手机号码格式错误')

	# 3.逻辑处理
	# 3.1通过验证码编号在redis中查找保存的图像验证码内容
	try:
		real_image_code = redis_store.get('Image_code_' + image_code_id)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='查询验证码失败')

	# 3.2判断验证码编号是否过期
	if not real_image_code:
		return jsonify(errno=RET.NODATA, errmsg='验证码已过期')

	# 3.3对比图像验证码
	if real_image_code.upper() != image_code.upper():
		return jsonify(errno=RET.DATAERR, errmsg='验证码输入错误')

	# 3.4添加一项验证----->判断该手机好是否注册过
	try:
		user = User.query.filter_by(mobile=mobile).first()
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR)

	if user:
		return jsonify(errno=RET.DATAEXIST, errmsg='该用户名已注册')

	# 4.发送短信验证码
	# 4.1生成验证码  6位 0补位
	sms_code_str = '%06d' % random.randint(0, 999999)
	current_app.logger.debug('sms_code: %s' % sms_code_str)

	# TODO(发送短信失败，待解决)
	# 4.2发送短信
	# result = CCP().send_template_sms(mobile, [sms_code_str, 5], 1)
	# if result != 0:
	# 	return jsonify(errno=RET.PARAMERR, errmsg='短信验证码发送失败')

	# 5.短信验证码保存到redis
	try:
		redis_store.set('SMS_' + mobile, sms_code_str, constants.SMS_CODE_REDIS_EXPIRES)

	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='短信验证码保存失败')

	# 返回成功信息
	return jsonify(errno=RET.OK, errmsg='短信验证码发送成功')


"""
注册验证码图像接口
URL：/image_code
请求方式： GET
参数：image_code_id（图像验证码编号
"""


@passport_blue.route('/image_code')
def index():
	# 1.获取参数
	image_code_id = request.args.get('image_code_id')

	# 2.生成验证码图像
	name, text, image_data = captcha.generate_captcha()

	# 3.保存验证码图像内容到redis中
	try:
		redis_store.set('Image_code_' + image_code_id, text, constants.IMAGE_CODE_REDIS_EXPIRES)
	except Exception as e:
		current_app.logger.error(e)
		return jsonify(errno=RET.DBERR, errmsg='保存验证码编号失败')

	# 4.返回验证码图像
	# 4.1创建响应对象
	response = make_response(image_data)

	# 4.2设置返回数据类型
	response.headers['Content-Type'] = 'image/jpg'

	return response
